#ifndef __PAGE_H__
#define __PAGE_H__

#include <asm/type.h>

#define PAGE_PRESENT_BIT 0x01
#define PAGE_WRITE_BIT 0x02
#define PAGE_USER_BIT 0x04
#define PAGE_HUGE_BIT 0x80
#define PAGE_GLOBAL_BIT 0x100


typedef struct
{
    u32_t present : 1;
    u32_t rw : 1;
    u32_t us : 1;
    u32_t pwd : 1;
    u32_t pcd : 1;
    u32_t access : 1;
    u32_t reserved : 6;
    u64_t addr : 36;
    u32_t sflag : 15;
    u32_t xd : 1;
} __attribute__((packed)) pml4_entry_t;

typedef struct
{
    u32_t present : 1;
    u32_t rw : 1;
    u32_t us : 1;
    u32_t pwd : 1;
    u32_t pcd : 1;
    u32_t access : 1;
    u32_t dirty : 1;
    u32_t huge : 1;//1-1G
    u32_t reserved : 4;
    u64_t addr : 36;
    u32_t sflag : 15;
    u32_t xd : 1;
} __attribute__((packed)) pdpt_entry_t;

typedef struct
{
    u32_t present : 1;
    u32_t rw : 1;
    u32_t us : 1;
    u32_t pwd : 1;
    u32_t pcd : 1;
    u32_t access : 1;
    u32_t dirty : 1;
    u32_t huge : 1;//1-2M
    u32_t reserved : 4;
    u64_t addr : 36;
    u32_t sflag : 15;
    u32_t xd : 1;
} __attribute__((packed)) pdt_entry_t;

typedef struct
{
    u32_t present : 1;
    u32_t rw : 1;
    u32_t us : 1;
    u32_t pwd : 1;
    u32_t pcd : 1;
    u32_t access : 1;
    u32_t dirty : 1;
    u32_t reserved : 5;
    u64_t addr : 36;
    u32_t sflag : 15;
    u32_t xd : 1;
} __attribute__((packed)) pt_entry_t;


extern u64_t g_pdpt[512];
static inline void invlpg(void *m)
{
    __asm__ __volatile__ ( "invlpg (%0)" : : "a"(m) : "memory" );
}

#endif //__PAGE_H__